import sys
import os
import platform
import fitz  # PyMuPDF
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout, 
                            QPushButton, QLabel, QProgressBar, QMessageBox, QFileDialog, 
                            QSpinBox)
from PyQt5.QtCore import QCoreApplication, Qt
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QUrl
from pdf2docx import Converter

class FileConverterApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("文件格式转换工具")
        self.setGeometry(100, 100, 600, 400)
        
        # 创建选项卡控件
        self.tabs = QTabWidget()
        
        # 创建三个选项卡页面
        self.tab_pdf2word = QWidget()
        self.tab_word2pdf = QWidget()
        self.tab_pdf2image = QWidget()
        
        # 添加选项卡
        self.tabs.addTab(self.tab_pdf2word, "PDF转Word")
        self.tabs.addTab(self.tab_word2pdf, "Word转PDF")
        self.tabs.addTab(self.tab_pdf2image, "PDF转图片")
        
        # 初始化每个选项卡UI
        self.init_pdf2word_tab()
        self.init_word2pdf_tab()
        self.init_pdf2image_tab()
        
        # 设置中央部件
        self.setCentralWidget(self.tabs)
        
        # 检查平台和依赖
        self.check_platform_dependencies()
        
    def init_pdf2word_tab(self):
        layout = QVBoxLayout()
        
        # 文件夹选择
        self.pdf2word_folder_btn = QPushButton("选择文件夹")
        self.pdf2word_folder_btn.clicked.connect(self.select_pdf2word_folder)
        layout.addWidget(self.pdf2word_folder_btn)
        
        # 显示选中路径
        self.pdf2word_folder_path = QLabel("未选择文件夹")
        layout.addWidget(self.pdf2word_folder_path)
        
        # 转换按钮
        self.pdf2word_convert_btn = QPushButton("开始转换")
        self.pdf2word_convert_btn.clicked.connect(self.pdf_to_word_convert)
        self.pdf2word_convert_btn.setEnabled(False)
        layout.addWidget(self.pdf2word_convert_btn)
        
        # 进度条
        self.pdf2word_progress = QProgressBar()
        layout.addWidget(self.pdf2word_progress)
        
        # 状态标签
        self.pdf2word_status = QLabel("状态: 等待选择文件夹")
        layout.addWidget(self.pdf2word_status)
        
        self.tab_pdf2word.setLayout(layout)
        
    def init_word2pdf_tab(self):
        layout = QVBoxLayout()
        
        # 文件夹选择
        self.word2pdf_folder_btn = QPushButton("选择文件夹")
        self.word2pdf_folder_btn.clicked.connect(self.select_word2pdf_folder)
        layout.addWidget(self.word2pdf_folder_btn)
        
        # 显示选中路径
        self.word2pdf_folder_path = QLabel("未选择文件夹")
        layout.addWidget(self.word2pdf_folder_path)
        
        # 转换按钮
        self.word2pdf_convert_btn = QPushButton("开始转换")
        self.word2pdf_convert_btn.clicked.connect(self.word_to_pdf_convert)
        self.word2pdf_convert_btn.setEnabled(False)
        layout.addWidget(self.word2pdf_convert_btn)
        
        # 进度条
        self.word2pdf_progress = QProgressBar()
        layout.addWidget(self.word2pdf_progress)
        
        # 状态标签
        self.word2pdf_status = QLabel("状态: 等待选择文件夹")
        layout.addWidget(self.word2pdf_status)
        
        self.tab_word2pdf.setLayout(layout)
        
    def init_pdf2image_tab(self):
        layout = QVBoxLayout()
        
        # 文件选择
        self.pdf2image_file_btn = QPushButton("选择PDF文件")
        self.pdf2image_file_btn.clicked.connect(self.select_pdf2image_file)
        layout.addWidget(self.pdf2image_file_btn)
        
        # 显示选中文件
        self.pdf2image_file_path = QLabel("未选择文件")
        layout.addWidget(self.pdf2image_file_path)
        
        # DPI设置
        layout.addWidget(QLabel("输出质量(DPI):"))
        self.pdf2image_dpi = QSpinBox()
        self.pdf2image_dpi.setRange(72, 600)
        self.pdf2image_dpi.setValue(300)
        layout.addWidget(self.pdf2image_dpi)
        
        # 转换按钮
        self.pdf2image_convert_btn = QPushButton("开始转换")
        self.pdf2image_convert_btn.clicked.connect(self.pdf_to_image_convert)
        self.pdf2image_convert_btn.setEnabled(False)
        layout.addWidget(self.pdf2image_convert_btn)
        
        # 打开文件夹按钮
        self.pdf2image_open_btn = QPushButton("打开输出文件夹")
        self.pdf2image_open_btn.clicked.connect(self.open_pdf2image_output)
        self.pdf2image_open_btn.setEnabled(False)
        layout.addWidget(self.pdf2image_open_btn)
        
        # 进度条
        self.pdf2image_progress = QProgressBar()
        layout.addWidget(self.pdf2image_progress)
        
        # 状态标签
        self.pdf2image_status = QLabel("状态: 等待选择文件")
        layout.addWidget(self.pdf2image_status)
        
        self.tab_pdf2image.setLayout(layout)
        
    def check_platform_dependencies(self):
        # 检查Word转PDF依赖
        self.has_win32com = False
        if platform.system().lower() == 'windows':
            try:
                from win32com import client
                self.has_win32com = True
            except ImportError:
                self.word2pdf_status.setText("缺少依赖: 请安装pywin32库")
                self.word2pdf_convert_btn.setEnabled(False)
        else:
            self.word2pdf_convert_btn.setEnabled(False)
            self.word2pdf_status.setText("提示: Word转PDF仅支持Windows系统")
            
    def select_pdf2word_folder(self):
        folder_path = QFileDialog.getExistingDirectory(self, "选择PDF文件夹", "")
        if folder_path:
            self.pdf2word_folder_path.setText(f"已选择: {folder_path}")
            self.pdf2word_convert_btn.setEnabled(True)
            self.current_pdf2word_folder = folder_path
            
    def select_word2pdf_folder(self):
        folder_path = QFileDialog.getExistingDirectory(self, "选择Word文件夹", "")
        if folder_path:
            self.word2pdf_folder_path.setText(f"已选择: {folder_path}")
            self.word2pdf_convert_btn.setEnabled(True)
            self.current_word2pdf_folder = folder_path
            
    def select_pdf2image_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "选择PDF文件", "", "PDF文件 (*.pdf)")
        if file_path:
            self.pdf2image_file_path.setText(f"已选择: {os.path.basename(file_path)}")
            self.pdf2image_convert_btn.setEnabled(True)
            self.current_pdf2image_path = file_path
            
    def pdf_to_word_convert(self):
        if not hasattr(self, 'current_pdf2word_folder'):
            QMessageBox.warning(self, "警告", "请先选择文件夹")
            return
            
        folder_path = self.current_pdf2word_folder
        pdf_files = [f for f in os.listdir(folder_path) if f.lower().endswith('.pdf')]
        
        if not pdf_files:
            QMessageBox.information(self, "提示", "未找到PDF文件")
            return
            
        total_files = len(pdf_files)
        self.pdf2word_progress.setRange(0, total_files)
        success_count = 0
        fail_count = 0
        error_log = []
        
        for i, file in enumerate(pdf_files):
            self.pdf2word_status.setText(f"正在转换: {file}")
            try:
                pdf_path = os.path.join(folder_path, file)
                word_filename = os.path.splitext(file)[0] + ".docx"
                word_path = os.path.join(folder_path, word_filename)
                
                if os.path.exists(word_path):
                    self.pdf2word_status.setText(f"已存在，跳过: {file}")
                    self.pdf2word_progress.setValue(i+1)
                    QApplication.processEvents()
                    continue
                
                cv = Converter(pdf_path)
                cv.convert(word_path)
                cv.close()
                
                success_count += 1
                self.pdf2word_status.setText(f"转换成功: {file}")
            except Exception as e:
                fail_count += 1
                error_log.append(f"{file}: {str(e)}")
                self.pdf2word_status.setText(f"转换失败: {file}")
            finally:
                self.pdf2word_progress.setValue(i+1)
                QApplication.processEvents()
        
        result_msg = f"转换完成: 成功{success_count}个, 失败{fail_count}个"
        if error_log:
            result_msg += "\n错误详情:\n" + "\n".join(error_log[:5])  # 只显示前5个错误
            if len(error_log) > 5:
                result_msg += f"\n...及{len(error_log)-5}个更多错误"
        
        QMessageBox.information(self, "结果", result_msg)
        self.pdf2word_status.setText("状态: 转换完成")
        
    def word_to_pdf_convert(self):
        if not hasattr(self, 'current_word2pdf_folder'):
            QMessageBox.warning(self, "警告", "请先选择文件夹")
            return
            
        if not self.has_win32com:
            QMessageBox.critical(self, "错误", "缺少win32com依赖，请安装pywin32")
            return
            
        folder_path = self.current_word2pdf_folder
        word_extensions = ('.doc', '.docx')
        word_files = [f for f in os.listdir(folder_path) if f.lower().endswith(word_extensions)]
        
        if not word_files:
            QMessageBox.information(self, "提示", "未找到Word文件")
            return
            
        total_files = len(word_files)
        self.word2pdf_progress.setRange(0, total_files)
        success_count = 0
        fail_count = 0
        error_log = []
        
        try:
            from win32com import client
            word = client.DispatchEx("Word.Application")
            word.Visible = False
            
            for i, file in enumerate(word_files):
                self.word2pdf_status.setText(f"正在转换: {file}")
                try:
                    word_path = os.path.join(folder_path, file)
                    pdf_filename = os.path.splitext(file)[0] + ".pdf"
                    pdf_path = os.path.join(folder_path, pdf_filename)
                    
                    if os.path.exists(pdf_path):
                        self.word2pdf_status.setText(f"已存在，跳过: {file}")
                        self.word2pdf_progress.setValue(i+1)
                        QApplication.processEvents()
                        continue
                    
                    doc = word.Documents.Open(os.path.abspath(word_path), ReadOnly=1)
                    doc.SaveAs(os.path.abspath(pdf_path), FileFormat=17)  # 17是PDF格式
                    doc.Close()
                    
                    success_count += 1
                    self.word2pdf_status.setText(f"转换成功: {file}")
                except Exception as e:
                    fail_count += 1
                    error_log.append(f"{file}: {str(e)}")
                    self.word2pdf_status.setText(f"转换失败: {file}")
                finally:
                    self.word2pdf_progress.setValue(i+1)
                    QApplication.processEvents()
        except Exception as e:
            QMessageBox.critical(self, "错误", f"Word应用初始化失败: {str(e)}")
            return
        finally:
            try:
                word.Quit()
            except:
                pass
        
        result_msg = f"转换完成: 成功{success_count}个, 失败{fail_count}个"
        if error_log:
            result_msg += "\n错误详情:\n" + "\n".join(error_log[:5])
            if len(error_log) > 5:
                result_msg += f"\n...及{len(error_log)-5}个更多错误"
        
        QMessageBox.information(self, "结果", result_msg)
        self.word2pdf_status.setText("状态: 转换完成")
        
    def pdf_to_image_convert(self):
        if not hasattr(self, 'current_pdf2image_path'):
            QMessageBox.warning(self, "警告", "请先选择PDF文件")
            return
            
        pdf_path = self.current_pdf2image_path
        dpi = self.pdf2image_dpi.value()
        output_dir = os.path.splitext(pdf_path)[0]
        
        try:
            doc = fitz.open(pdf_path)
            total_pages = len(doc)
            self.pdf2image_progress.setRange(0, total_pages)
            
            if not os.path.exists(output_dir):
                os.makedirs(output_dir, exist_ok=True)
            
            for i in range(total_pages):
                page = doc.load_page(i)
                pix = page.get_pixmap(dpi=dpi)
                output_path = f"{output_dir}/{os.path.basename(pdf_path)}_{i + 1}.png"
                pix.save(output_path)
                
                self.pdf2image_progress.setValue(i + 1)
                self.pdf2image_status.setText(f"正在转换第 {i+1}/{total_pages} 页")
                QApplication.processEvents()
            
            self.pdf2image_status.setText("状态: 转换完成")
            self.pdf2image_open_btn.setEnabled(True)
            self.current_pdf2image_output_dir = output_dir
            QMessageBox.information(self, "成功", f"已转换 {total_pages} 页到:\n{output_dir}")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"转换失败: {str(e)}")
        finally:
            self.pdf2image_progress.reset()
            
    def open_pdf2image_output(self):
        if hasattr(self, 'current_pdf2image_output_dir') and os.path.exists(self.current_pdf2image_output_dir):
            QDesktopServices.openUrl(QUrl.fromLocalFile(self.current_pdf2image_output_dir))
        else:
            QMessageBox.warning(self, "警告", "输出目录不存在")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = FileConverterApp()
    window.show()
    sys.exit(app.exec_())